<!--
 * @PageName: @表格筛选组件
 * @Description: 
 * @FilePath: /glm-mes-pc/src/components/TableFilter/index.vue
-->
<template>
	<span class="header-filter-container">
		<!-- 表头文字内容 -->
		<span>{{ headerTitle }}</span>
		<el-popover placement="bottom" width="250" trigger="click" popper-class="popover-diy" :visible="visible" ref="popoverRef">
			<template #reference>
				<!-- svg筛选图标 -->
				<svg-icon icon-class="shaixuan1" @click.native.stop="openPopover" :class="[isFiltered ? 'high-light' : '', 'header-filter-icon']" />
			</template>

			<div v-loading="filterLoading">
				<!-- 前端模糊搜索区 -->
				<el-input class="my-input" type="type" v-model="searchContent" placeholder="支持模糊筛选" @input="fuzzySearch"></el-input>
				<!-- 勾选区 -->
				<div class="checkbox-container">
					<el-tree-v2
						ref="treeRef"
						:data="filterOptions"
						:props="{ value: 'id', label: 'label', children: 'children' }"
						show-checkbox
						:height="235"
						:filter-method="filterMethod"
						@check-change="checkChange"
					/>
				</div>
				<!-- 底部操作区 -->
				<div class="popper-button-container">
					<el-button link type="primary" @click="handleFilter">筛选</el-button>
					<el-button link @click="resetSingleFilter">重置</el-button>
				</div>
			</div>
		</el-popover>
	</span>
</template>

<script setup>
import { camelToSnakeCase } from '@/utils'
let props = defineProps({
	// 表格表头显示中文内容
	headerTitle: {
		type: String,
		default: ''
	},
	// 表头对应字段名
	headerProp: {
		type: String,
		default: ''
	},
	filterLoading: Boolean,
	activeIndex: Number,
	isActive: Boolean,
	filterOptions: Array
})
const { headerTitle, headerProp, filterLoading, activeIndex, isActive, filterOptions } = toRefs(props)
const { proxy } = getCurrentInstance()
const searchContent = ref('')
const checkedList = ref([])
const { addParamsAndGetList } = inject('grandFather')

/* 是否高亮筛选图标 */
const isFiltered = ref(false)
const visible = ref(false)

const emit = defineEmits(['toggleFilter', 'resetActiveFilter', 'updateStorageFilterObject', 'removeCurrentCondition'])

watch(isActive, (newVal) => {
	visible.value = newVal
})

/* 显示筛选弹窗并查询数据：多列同时筛选需要携带对应数组数据 */
const openPopover = () => {
	emit('toggleFilter', activeIndex.value, camelToSnakeCase(headerProp.value), headerProp.value + 's')
}

/* 模糊搜索 */
const treeRef = ref(null)
const fuzzySearch = (query) => {
	treeRef.value.filter(query)
}

/* 前端过滤方法 */
const filterMethod = (query, node) => {
	return node.label.includes(query)
}

/* 勾选变化 */
const checkChange = (data, checked) => {
	if (checked) {
		checkedList.value.push(data.id)
	} else {
		const index = checkedList.value.indexOf(data.id)
		index > -1 && checkedList.value.splice(index, 1)
	}
}

/* 筛选 */
const handleFilter = () => {
	if (!checkedList.value.length) {
		return proxy.$modal.msgWarning('请选择筛选项')
	}
	// 更新筛选集合
	emit('updateStorageFilterObject', {
		[headerProp.value + 's']: checkedList.value
	})
	// 调用表格查询相关方法
	addParamsAndGetList()

	// 高亮筛选图标
	isFiltered.value = true
	// 关闭弹窗
	emit('resetActiveFilter')
}

/* 重置单个筛选项 */
const resetSingleFilter = () => {
	// 重置基础项
	resetBaseFilterInfo()
	// 关闭弹窗
	emit('resetActiveFilter')
	// 从存储中移除当前筛选列的配置并刷新表格列表
	emit('removeCurrentCondition', headerProp.value + 's')
}

/* 重置筛选项基础设置 */
const resetBaseFilterInfo = () => {
	// 树形组件取消所有勾选
	treeRef.value?.setCheckedKeys([])
	// 清空勾选集合
	checkedList.value = []
	// 清空输入框
	searchContent.value = ''
	treeRef.value?.filter('')
	isFiltered.value = false
}

defineExpose({
	resetBaseFilterInfo,
	isFiltered
})
</script>

<style lang="scss" scoped>
.header-filter-container {
	display: flex;
	align-items: center;
	.header-filter-icon {
		color: #a8abb2;
		width: 24px;
		height: 14px;
		margin-left: 8px;
		/* 去除默认边框 */
		&:focus {
			outline: none;
		}
	}
}
.checkbox-container {
	height: 250px;
	overflow-y: auto;
	margin-top: 10px;
	::v-deep(.el-tree-node__expand-icon) {
		display: none;
	}
}
.loading-text {
	text-align: center;
	padding: 6px;
	font-size: 12px;
	color: #a8a6a6;
}
.popper-button-container {
	padding-top: 10px;
	text-align: right;
}
.high-light {
	color: #265bae !important;
}

/* BetterScroll scrollbar custom styles */
.bscroll-vertical-scrollbar {
	position: absolute;
	top: 2px;
	bottom: 2px;
	right: 2px;
	width: 6px;
	background: rgba(0, 0, 0, 0.1);
	border-radius: 6px;
	transition: opacity 0.3s;
	opacity: 0;
}

.bscroll-vertical-scrollbar .bscroll-indicator {
	position: absolute;
	background: rgba(0, 0, 0, 0.5);
	border-radius: 6px;
	width: 100%;
}
</style>
